home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / LIBRARY / PCTV3N3 / DOSDISK.C < prev    next >
Text File  |  1992-06-11  |  3KB  |  119 lines

  1. /* DOSDISK.C */
  2.  
  3. #include <ctype.h>
  4. #include <dir.h>
  5. #include <dos.h>
  6. #include <errno.h>
  7. #include <stdio.h>
  8.  
  9. #define DOS_DATA_SEG  0x0050
  10.  
  11. /***/
  12. /* Returns drive currently attached to block device
  13.    defined by 'drive'. */
  14. char get_logical_drive(char drive)
  15. {
  16. char cur_drive;       /* Current drive attached to block device. */
  17. union REGS regs;      /* Registers for interrupt calls. */
  18.  
  19. /* Default to current drive. */
  20. drive = drive ? toupper(drive) : (getdisk() + 'A');
  21.  
  22. /* Check for valid drive letter. */
  23. if (!isalpha(drive))
  24.   {
  25.   cur_drive = 0;
  26.   _doserrno = EINVDRV;
  27.   }
  28. else
  29.   /* Check for DOS version 3.20 or above. */
  30.   if (_osmajor > 3 || _osmajor == 3 && _osminor >= 20)
  31.     {
  32.     /* IOCTL request 0x0E (get logical drive). */
  33.     regs.x.ax = 0x440E;
  34.  
  35.     /* Drive number (1 = A, 2 = B, etc) is in BL. */
  36.     regs.h.bl = drive - ('A' - 1);
  37.  
  38.     intdos(®s, ®s);
  39.  
  40.     if (regs.x.cflag)
  41.       /* Carry flag set, error in _doserrno. */
  42.       cur_drive = 0;
  43.     else
  44.       /* Return code of 0 in AL means only one drive attached
  45.          to block device. */
  46.       cur_drive = regs.h.al == 0 ? drive : regs.h.al + ('A' - 1);
  47.     }
  48.   else
  49.     /* For lower versions of DOS, only drives
  50.        A and B are interchangeable. */
  51.     if (drive == 'A' || drive == 'B')
  52.       {
  53.       int86(0x11, ®s, ®s);
  54.  
  55.       /* Bit 0 in AX is 1 if diskette drives are present. */
  56.       if (regs.x.ax & 0x0001)
  57.         if (((regs.x.ax & 0xC0) >> 6) == 0)
  58.           /* Only one diskette installed. */
  59.           cur_drive = drive == 'A' || drive == 'B'
  60.           ? peekb(DOS_DATA_SEG, 0x0004) + 'A' : drive;
  61.         else
  62.           /* More than one diskette installed. */
  63.           cur_drive = drive;
  64.       else
  65.         /* No diskette drive. */
  66.         {
  67.         cur_drive = 0;
  68.         _doserrno = EINVDRV;
  69.         }
  70.       }
  71.     else
  72.       cur_drive = drive;
  73.  
  74. return (cur_drive);
  75. }
  76.  
  77. /***/
  78. /* Attaches logical drive to block device
  79.    if not already attached. */
  80. char set_logical_drive(char drive)
  81. {
  82. char cur_drive;    /* Current drive attached to block device. */
  83. union REGS regs;   /* Registers for interrupt calls. */
  84.  
  85. /* Default to current drive. */
  86. drive = drive ? toupper(drive) : (getdisk() + 'A');
  87.  
  88. if ((cur_drive = get_logical_drive(drive = toupper(drive)))
  89.    != 0 && cur_drive != drive)
  90.   {
  91.   /* REPLACE THIS WITH WHATEVER YOU WANT TO PROMPT FOR CHANGE. */
  92.   printf("Insert disk for drive %c: and press RETURN", drive);
  93.   getchar();
  94.  
  95.   /* Check for DOS version 3.20 or above. */
  96.   if (_osmajor > 3 || _osmajor == 3 && _osminor >= 20)
  97.     {
  98.     /* IOCTL request 0x0F (set logical drive). */
  99.     regs.x.ax = 0x440F;
  100.  
  101.     /* Drive number (1 = A, 2 = B, etc) is in BL. */
  102.     regs.h.bl = drive - ('A' - 1);
  103.  
  104.     intdos(®s, ®s);
  105.  
  106.     if (regs.x.cflag)
  107.       /* Carry flag set, error in _doserrno. */
  108.       drive = 0;
  109.     }
  110.   else
  111.     /* For lower versions of DOS, only drives A and B
  112.        are interchangeable. */
  113.     if (drive == 'A' || drive == 'B')
  114.       pokeb(DOS_DATA_SEG, 0x0004, drive - 'A');
  115.   }
  116.  
  117. return (cur_drive);
  118. }
  119.